package com.dongdongshop.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.dongdongshop.constant.SeckillContant;
import com.dongdongshop.mapper.TbSeckillGoodsMapper;
import com.dongdongshop.pojo.TbSeckillGoods;
import com.dongdongshop.pojo.TbSeckillGoodsExample;
import com.dongdongshop.service.SeckillGoodsService;
import com.dongdongshop.util.RedisUtil;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@Service
@DubboService
public class SeckillGoodsServiceImpl implements SeckillGoodsService {

    @Resource
    private TbSeckillGoodsMapper tbSeckillGoodsMapper;

    @Autowired
    private RedisTemplate       redisTemplate;


    @Resource
    private RocketMQTemplate rocketMQTemplate;


    @Override
    public void catchPreHot() {
        //将redis的string类型的value值序列化
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        /*查询秒杀商品,每天0点开始查询,并存入redis缓存中*/
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String startDateStr = sdf.format(date) + " 00:00:00";//今日开始时间
        String endDateStr = sdf.format(date) + " 23:59:59";//今日结束时间
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        try {
            Date startDate = sdf1.parse(startDateStr);
            Date endDate = sdf1.parse(endDateStr);
            /*查询在这个时间开始秒杀的商品*/
            TbSeckillGoodsExample example = new TbSeckillGoodsExample();
            TbSeckillGoodsExample.Criteria criteria = example.createCriteria();
            criteria.andStartTimeGreaterThan(startDate);//大于 今日开始时间
            criteria.andEndTimeLessThan(endDate);//小于 今日结束时间
            criteria.andStockCountGreaterThan(0);//库存剩余数>0
            List<TbSeckillGoods> tbSeckillGoods = this.tbSeckillGoodsMapper.selectByExample(example);
            /*存入redis*/
            tbSeckillGoods.stream().forEach(tbSeckillGood->{
//                Integer o = (Integer)redisTemplate.boundValueOps(SeckillContant.STOCKCOUNT + tbSeckillGood.getId()).get();
//                tbSeckillGood.setStockCount(o);
                redisTemplate.boundHashOps(SeckillContant.SECKILL).put(tbSeckillGood.getId(),tbSeckillGood);
                /*将库存数存入redis*/
                System.out.println(tbSeckillGood.getStockCount());
                redisTemplate.boundValueOps(SeckillContant.STOCKCOUNT + tbSeckillGood.getId()).set(tbSeckillGood.getStockCount().toString());

            });
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    @Override
    public List<TbSeckillGoods> findSeckillList() {
        List<TbSeckillGoods> values = redisTemplate.boundHashOps(SeckillContant.SECKILL).values();
        return values;
    }

    @Override
    public TbSeckillGoods selectSeckillItemById(Long id) {
        TbSeckillGoods seckillGoods = (TbSeckillGoods)redisTemplate.boundHashOps(SeckillContant.SECKILL).get(id);
        //将redis的string类型的value值序列化
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        String o = (String)redisTemplate.boundValueOps(SeckillContant.STOCKCOUNT + id).get();
        seckillGoods.setStockCount(Integer.valueOf(o));
        return seckillGoods;
    }

    @Override
    public void createOrder(Long id, String name) throws Exception {
        //将redis的string类型的value值序列化
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        //获取所以秒杀商品
        TbSeckillGoods seckillGoods = (TbSeckillGoods)redisTemplate.boundHashOps(SeckillContant.SECKILL).get(id);
        /*取出库存数*/
        String stockCount = (String) redisTemplate.boundValueOps(SeckillContant.STOCKCOUNT + id).get();
        long num = Long.parseLong(stockCount);
        if (num <= 0 ){
            //商品售完需要同步数据库
            throw new Exception("商品已售完");
        }
        //扣减库存
//        seckillGoods.setStockCount(seckillGoods.getStockCount() - 1);
        //库存减一并返回运算之后的值
        Long decrement = redisTemplate.boundValueOps(SeckillContant.STOCKCOUNT + id).decrement();
        redisTemplate.boundValueOps(SeckillContant.STOCKCOUNT + id).set(decrement.toString());
        //添加覆盖缓存
//        redisTemplate.boundHashOps(SeckillContant.SECKILL).put(id,seckillGoods);
        //如果是最后一件同步数据库
        if (decrement <= 0 ){
            //商品售完需要同步数据库
            seckillGoods.setStockCount(decrement.intValue());
            tbSeckillGoodsMapper.updateByPrimaryKeySelective(seckillGoods);
        }
        /*将用户放入队列并下单*/
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("id",id);
        jsonObject.put("userName",name);
        rocketMQTemplate.convertAndSend("seckill-goods-topic",jsonObject);

    }
}
